
#pragma once

#include <cstdlib>
#include <cstdint>
#include <cassert>
#include <cfloat>
#include <cstring>
#include <cmath>

#include <map>
#include <set>
#include <list>
#include <queue>
#include <stack>
#include <regex>
#include <array>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#include <forward_list>
#include <algorithm>
#include <functional>
#include <string>
#include <memory>
#include <random>
#include <atomic>
#include <mutex>
#include <thread>
#include <condition_variable>
#include <sstream>
#include <fstream>
#include <iostream>
#include <filesystem>

#define NOMINMAX 1

#include <vulkan/vulkan.h>

#define BEGIN_NS_VULKAN namespace Vulkan {
#define END_NS_VULKAN }
#define USING_NS_VULKAN using namespace Vulkan;

#define DEFINE_SHARE_REF(className) class className; using className##Ref = std::shared_ptr<className>;

BEGIN_NS_VULKAN

DEFINE_SHARE_REF(Device)
DEFINE_SHARE_REF(SwapChain)
DEFINE_SHARE_REF(Pipeline)
DEFINE_SHARE_REF(Shader)
DEFINE_SHARE_REF(DescriptorSet)
DEFINE_SHARE_REF(UniformBuffer)
DEFINE_SHARE_REF(Texture)
DEFINE_SHARE_REF(Model)
DEFINE_SHARE_REF(Model2D)
DEFINE_SHARE_REF(Model2DTex)
DEFINE_SHARE_REF(Model3D)

END_NS_VULKAN

DEFINE_SHARE_REF(GLWindow)

DEFINE_SHARE_REF(Listener)
using ListenerWeekRef = std::weak_ptr<Listener>;

DEFINE_SHARE_REF(Timer)
using TimeCallBack = std::function<void()>;

DEFINE_SHARE_REF(MouseListener)
class MouseEvent;

DEFINE_SHARE_REF(KeyListener)
class KeyEvent;

DEFINE_SHARE_REF(WindowEventListener)
class WindowEvent;

DEFINE_SHARE_REF(CustomEventListener)
class CustomEvent;
